package com.alogic.xscript.plugins;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;

import com.alogic.xscript.ExecuteWatcher;
import com.alogic.xscript.Logiclet;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.doc.XsObject;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;

/**
 * 正则表达式匹配
 * @author yyduan
 * 
 * @since 1.6.11.57
 * @version 1.6.12.35 [20190528]  <br>
 * - 删除无用代码 <br>
 *
 * @version 1.6.13.23 [20201030 duanyy] <br>
 * - 优化xscript的日志机制  <br>
 *
 * @version 1.6.13.32 [20210128 duanyy] <br>
 * - 修正bug
 */
public abstract class RegexMatcher extends Segment {
	protected String id = "";
	protected Pattern pattern = null;
	protected String $value = "";
	protected String var = "v%d";
	
	public RegexMatcher(String tag, Logiclet p) {
		super(tag, p);
	}

	@Override
	public void configure(Properties p){
		super.configure(p);
		
		id = PropertiesConstants.getString(p,"id","$" + this.getXmlTag(),true);
		var = PropertiesConstants.getString(p,"var",var,true);
		$value = PropertiesConstants.getRaw(p,"value",$value);
		
		String regex = PropertiesConstants.getString(p,"pattern","",true);
		if (StringUtils.isNotEmpty(regex)){
			try {
				pattern = Pattern.compile(regex);
			}catch (Exception ex){
				log(String.format("Failed to compile regex:%s",regex),LOG_ERROR);
			}
		}
	}

	/**
	 * 一段匹配
	 */
	public static class Single extends RegexMatcher{
		public Single(String tag, Logiclet p) {
			super(tag, p);
		}

		protected void onExecute(XsObject root,XsObject current, LogicletContext ctx, ExecuteWatcher watcher) {
			if (pattern != null){
				String value = PropertiesConstants.transform(ctx, $value, "");
				if (StringUtils.isNotEmpty(value)){
					Matcher matcher = pattern.matcher(value);
					if (matcher.find()){
						ctx.SetValue(id, "true");
						for (int i = 1; i < matcher.groupCount() + 1 ; i ++){
							ctx.SetValue(String.format(var, i), matcher.group(i));
						}
						super.onExecute(root, current, ctx, watcher);
					}else{
						ctx.SetValue(id, "false");
					}
				}
			}
		}
	}

	/**
	 * 多段匹配
	 */
	public static class Multi extends RegexMatcher{

		public Multi(String tag, Logiclet p) {
			super(tag, p);
		}

		protected void onExecute(XsObject root,XsObject current, LogicletContext ctx, ExecuteWatcher watcher) {
			if (pattern != null){
				String value = PropertiesConstants.transform(ctx, $value, "");
				if (StringUtils.isNotEmpty(value)){
					boolean found = false;
					Matcher matcher = pattern.matcher(value);
					while (matcher.find()){
						found = true;

						for (int i = 1; i < matcher.groupCount() + 1 ; i ++){
							ctx.SetValue(String.format(var, i), matcher.group(i));
						}
						super.onExecute(root, current, ctx, watcher);
					}
					ctx.SetValue(id, BooleanUtils.toStringTrueFalse(found));
				}
			}
		}
	}

}
